package rpc.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import rpc.utils.TypeSafe;

/*********
 *
 *
 *@author 197
 *@date 2020/6/19 18:17
 *
 **/


public class FlowMap implements java.io.Serializable {

  private Map<String, Object> data;

  public FlowMap(Map<String, Object> data) {
    this();
    this.data.putAll(data);
  }

  public FlowMap() {
    this.data = new HashMap<>();
  }

  public FlowMap(String key, Object value) {
    this.appendInner(key, value);
  }

  public FlowMap(String key1, Object value1, String key2, Object value2) {
    this.appendInner(key1, value1);
    this.appendInner(key2, value2);
  }

  protected void appendInner(String key, Object value) {
    if (value != null) {
      if (value instanceof FlowMap) {
        this.data.putAll(((FlowMap) value).data);
      } else {
        this.data.put(key, value);
      }
    } else {
      this.data.remove(key);
    }
  }

  public FlowMap append(String key, Object value) {
    this.appendInner(key, value);
    return this;
  }

  public FlowMap append(String key1, Object value1, String key2, Object value2) {
    this.appendInner(key1, value1);
    this.appendInner(key2, value2);
    return this;
  }

  public FlowMap append(String key1, Object value1, String key2, Object value2, String key3,
      Object value3) {
    this.appendInner(key1, value1);
    this.appendInner(key2, value2);
    this.appendInner(key3, value3);
    return this;
  }

  public FlowMap append(String key1, Object value1, String key2, Object value2, String key3,
      Object value3, String key4, Object value4) {
    this.appendInner(key1, value1);
    this.appendInner(key2, value2);
    this.appendInner(key3, value3);
    this.appendInner(key4, value4);
    return this;
  }

  public String ns(String key) {
    return this.s(key, "");
  }

  public String s(String key, String dv) {
    Object o = this.data.get(key);
    return TypeSafe.anyToString(o, dv);
  }

  public Map<String, Object> toMap() {
    return this.data;
  }

  public boolean containsKey(String key) {
    return this.data.containsKey(key);
  }

  public Object o(String key) {
    return data.get(key);
  }

  public List<FlowMap> nlm(String key) {
    List<FlowMap> lm = lm(key);
    return CollectionUtils.isNotEmpty(lm) ? lm : new ArrayList<>();
  }

  @SuppressWarnings("unchecked")
  public List<FlowMap> lm(String key) {
    Object o = data.get(key);
    return (List<FlowMap>) (o);
  }

  public long l(String key) {
    return TypeSafe.anyToLong(data.get(key));
  }

  public List<String> nls(String key) {
    Object o = this.data.get(key);
    List<String> list;
    if (o instanceof List) {
      List<Object> tmp = (List<Object>) o;
      list = tmp.stream().map(String::valueOf).collect(Collectors.toList());
      return list;
    } else {
      list = new ArrayList<>();
    }
    this.data.put(key, list);
    return list;
  }

  public Map<String, Object> nm(String key) {
    Object o = this.data.get(key);
    Map<String, Object> retMap;
    if (o instanceof Map) {
      retMap = (Map<String, Object>) o;
    } else {
      retMap = new HashMap<>();
    }
    this.data.put("key", retMap);
    return retMap;
  }
}
